home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / exec / copymem.c < prev    next >
C/C++ Source or Header  |  1996-09-13  |  3KB  |  159 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: copymem.c,v 1.5 1996/09/13 17:51:22 digulla Exp $
  4.     $Log: copymem.c,v $
  5.     Revision 1.5  1996/09/13 17:51:22  digulla
  6.     Use IPTR
  7.  
  8.     Revision 1.4  1996/08/13 13:55:59  digulla
  9.     Replaced __AROS_LA by __AROS_LHA
  10.     Replaced some __AROS_LH*I by __AROS_LH*
  11.     Sorted and added includes
  12.  
  13.     Revision 1.3  1996/08/01 17:41:07  digulla
  14.     Added standard header for all files
  15.  
  16.     Desc:
  17.     Lang:
  18. */
  19. #include <aros/libcall.h>
  20. #include "machine.h"
  21.  
  22. /*****************************************************************************
  23.  
  24.     NAME */
  25.     #include <clib/exec_protos.h>
  26.  
  27.     __AROS_LH3I(void, CopyMem,
  28.  
  29. /*  SYNOPSIS */
  30.     __AROS_LHA(APTR,  source, A0),
  31.     __AROS_LHA(APTR,  dest,   A1),
  32.     __AROS_LHA(ULONG, size,   D0),
  33.  
  34. /*  LOCATION */
  35.     struct ExecBase *, SysBase, 104, Exec)
  36.  
  37. /*  FUNCTION
  38.     Copy some memory from one destination in memory to another using
  39.     a fast copying method.
  40.  
  41.     INPUTS
  42.     source - Pointer to source area
  43.     dest   - Pointer to destination
  44.     size   - number of bytes to copy
  45.  
  46.     RESULT
  47.  
  48.     NOTES
  49.     The source and destination area are not allowed to overlap.
  50.  
  51.     EXAMPLE
  52.  
  53.     BUGS
  54.  
  55.     SEE ALSO
  56.     CopyMemQuick()
  57.  
  58.     INTERNALS
  59.  
  60.     HISTORY
  61.     24-10-95    Created by M. Fleischer
  62.  
  63. ******************************************************************************/
  64. {
  65.     __AROS_FUNC_INIT
  66.  
  67.     UBYTE *src=(UBYTE *)source,*dst=(UBYTE *)dest;
  68.     ULONG mis,low,high;
  69.  
  70.     /*
  71.     I try to fall back to copying LONGs if possible. To do this I copy
  72.     the misaligned leading bytes of the source first. I use sizeof(LONG)
  73.     instead of LONGALIGN because it is sometimes faster.
  74.     */
  75.     mis =(IPTR)src&(sizeof(LONG)-1);
  76.     if(mis>size)
  77.     mis=size;
  78.     size-=mis;
  79.  
  80.     if(mis)
  81.       do
  82.     *dst++=*src++;
  83.       while(--mis);
  84.  
  85.     /*
  86.     The source has the right alignment now. All I need to do is to
  87.     check if this is true for the destination, too.
  88.     */
  89.     if(!((IPTR)dst&(LONGALIGN-1)))
  90.     {
  91.     /* Yes. I may copy LONGs. */
  92.     LONG *s=(LONG *)src,*d=(LONG *)dst;
  93.     ULONG longs;
  94.  
  95.     /* How many of them? */
  96.     longs=size/sizeof(LONG);
  97.  
  98.     /*
  99.         To minimize the loop overhead I copy more than one (eight) LONG per
  100.         iteration. Therefore I need to split size into size/8 and the rest.
  101.     */
  102.     low =longs&7;
  103.     high=longs/8;
  104.  
  105.     /* Then copy for both parts */
  106.     if(low)
  107.         do
  108.         *d++=*s++;
  109.         while(--low);
  110.  
  111.     if(high)
  112.         do
  113.         {
  114.         *d++=*s++;
  115.         *d++=*s++;
  116.         *d++=*s++;
  117.         *d++=*s++;
  118.         *d++=*s++;
  119.         *d++=*s++;
  120.         *d++=*s++;
  121.         *d++=*s++;
  122.         }while(--high);
  123.  
  124.     /* Get the rest. */
  125.     size&=sizeof(LONG)-1;
  126.     src=(UBYTE *)s;
  127.     dst=(UBYTE *)d;
  128.     }
  129.  
  130.     /* The remaining job can only be done by copying single bytes. */
  131.     low =size&7;
  132.     high=size/8;
  133.  
  134.     /* Copy for both parts */
  135.     if(low)
  136.       do
  137.     *dst++=*src++;
  138.       while(--low);
  139.  
  140.     /*
  141.     Partly unrolled copying loop. The predecrement helps the compiler to
  142.     find the best possible loop. The if is necessary to do this.
  143.     */
  144.     if(high)
  145.     do
  146.     {
  147.         *dst++=*src++;
  148.         *dst++=*src++;
  149.         *dst++=*src++;
  150.         *dst++=*src++;
  151.         *dst++=*src++;
  152.         *dst++=*src++;
  153.         *dst++=*src++;
  154.         *dst++=*src++;
  155.     }while(--high);
  156.     __AROS_FUNC_EXIT
  157. } /* CopyMem */
  158.  
  159.